package com.jvm123.blog.service

import com.jvm123.blog.dao.CollectPostRelationshipRepos
import com.jvm123.blog.dao.CollectRepos
import com.jvm123.blog.entity.Collect
import com.jvm123.blog.entity.CollectPostRelationship
import com.jvm123.blog.entity.Post
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

import java.util.function.Consumer

/**
 *
 * @author yawn http://jvm123.com
 *     2019/10/22 20:21
 */
@Service
class CollectServiceImpl implements CollectService {

    @Autowired
    CollectRepos collectRepos
    @Autowired
    CollectPostRelationshipRepos relationshipRepos
    @Autowired
    PostService postService
    @Autowired
    TermService termService

    @Override
    List<Collect> findAll() {
        collectRepos.findAll().toList()
    }

    @Override
    List<Collect> findByType(String type) {
        collectRepos.findByType(type)
    }

    @Override
    Collect findOne(Long id) {
        Optional<Collect> collectOptional = collectRepos.findById(id)
        if (collectOptional.isPresent()) {
            Collect collect = collectOptional.get()
            addPostList(collect)
            return collect
        }
        null
    }

    @Override
    boolean update(Collect co) {
        long id = co.getId()
        Collect collect = findOne(id)
        if (collect == null) {
            co.setDate(new Date())
            collectRepos.save(co)
            return true
        } else {
            collect.setTitle(co.title)
            collect.setContent(co.content)
            collect.setType(co.type)
            collect.setBlogUrl(co.blogUrl)
            collectRepos.save(collect)
            return true
        }

    }

    @Override
    boolean relate(long id, String tag, String category) {
        Set<CollectPostRelationship> set = relationshipRepos.findByCollectIdOrderByPostOrder(id).toSet()
        List<Long> postIds = termService.findPostIdByTag(tag)
        postIds.addAll(termService.findPostIdByCategory(category))
        for (Long postId : postIds) {
            if (postId != null && postId > 0) {
                CollectPostRelationship relationship = new CollectPostRelationship(postId: postId, collectId: id, postOrder: 999)
                boolean contain = false
                for (CollectPostRelationship relate : set) {
                    if (relate.postId == postId && relate.collectId == id) {
                        contain = true
                        break
                    }
                }
                if (!contain) {
                    relationshipRepos.save(relationship)
                }
            }
        }
        removeRepeatRelation(set)
    }

    @Override
    boolean removeRepeatRelation(Collection<CollectPostRelationship> collection) {
        Jdk8Utils.OpRepeatElement(collection, new Consumer<CollectPostRelationship>() {
            @Override
            void accept(CollectPostRelationship relationship) {
                removeRelation(relationship.id)
            }
        })
    }

    @Override
    boolean removeRelation(long id) {
        CollectPostRelationship relationship = new CollectPostRelationship()
        relationshipRepos.delete(relationship)
        true
    }

    @Override
    boolean removeRelation(long collectId, long postId) {
        CollectPostRelationship relationship = relationshipRepos.findFirstByCollectIdAndPostId(collectId, postId)
        removeRelation(relationship.id)
    }

    @Override
    List<Collect> findWithPosts() {
        List<Collect> list = collectRepos.findAll().toList()
        for (Collect collect : list) {
            addPostList(collect)
        }
        list
    }

    private void addPostList(Collect collect) {
        List<Post> postList = []
        List<CollectPostRelationship> list = relationshipRepos.findByCollectIdOrderByPostOrder(collect.id)
        for (CollectPostRelationship relationship : list) {
            Post post = postService.findPostWithTags(relationship.postId)
            if (post != null) {
                postList << post
            }
        }
        collect.postList = postList
    }
}
